﻿namespace Blaze.Editor.BMFontExtensions
{
    using UnityEditor;
    using UnityEngine;

    public class BMFontConverter
    {
        public static void Apply(Object[] selectedObjects)
        {
            if (Selection.objects == null) return;
            if (Selection.objects.Length == 0)
            {
                Debug.LogWarning("没有选中fnt文件，或者图片文件");
                return;
            }
            //至少需要保证选中文件的目录下面有fnt文件，否则不会生成字体  
            Font myFont = null;
            TextAsset data = null;
            var filePath = "";
            Material mat = null;
            Texture2D tex = null;
            var bln = false;

            //不管选中fnt、png、mat、fontsettings其中的任何一个，都可以创建字体  
            foreach (var o in selectedObjects)
            {
                if (o is TextAsset)
                {
                    data = o as TextAsset;
                    bln = true;
                }
                else if (o is Material)
                {
                    mat = o as Material;
                    bln = true;
                }
                else if (o is Texture2D)
                {
                    tex = o as Texture2D;
                    bln = true;
                }
                else if (o is Font)
                {
                    myFont = o as Font;
                    bln = true;
                }
                if (bln)
                {
                    filePath = AssetDatabase.GetAssetPath(o);
                    filePath = filePath.Substring(0, filePath.LastIndexOf('.'));
                }
            }

            //获取fnt文件，我们在这里加一次判断，为了可以直接选择图片也能导出字体  
            var dataPathName = filePath + ".fnt";
            if (data == null)
                data = (TextAsset) AssetDatabase.LoadAssetAtPath(dataPathName, typeof (TextAsset));
            if (data == null)
            {
                Debug.LogWarning("没有找到fnt文件，或者文件名称和图片名称不匹配");
                return;
            }

            var matPathName = filePath + ".mat";
            var fontPathName = filePath + ".fontsettings";
            var texPathName = filePath + ".png";

            //获取图片，如果没有图片，不影响，可以生成之后，再手动设置  
            if (tex == null)
            {
                tex = (Texture2D) AssetDatabase.LoadAssetAtPath(texPathName, typeof (Texture2D));
            }
            if (tex == null)
            {
                Debug.LogWarning("没找到图片，或者图片名称和fnt文件名称不匹配");
            }

            //获取材质，如果没有则创建对应名字的材质  
            if (mat == null)
            {
                mat = (Material) AssetDatabase.LoadAssetAtPath(matPathName, typeof (Material));
            }
            if (mat == null)
            {
                mat = new Material(Shader.Find("GUI/Text Shader"));
                AssetDatabase.CreateAsset(mat, matPathName);
            }
            else
            {
                mat.shader = Shader.Find("GUI/Text Shader");
            }
            mat.SetTexture("_MainTex", tex);

            //获取font文件，如果没有则创建对应名字的font文件  
            if (myFont == null)
            {
                myFont = (Font) AssetDatabase.LoadAssetAtPath(fontPathName, typeof (Font));
            }
            if (myFont == null)
            {
                myFont = new Font();
                AssetDatabase.CreateAsset(myFont, fontPathName);
            }
            myFont.material = mat;

            var mbFont = new BMFont();
            BMFontReader.Load(mbFont, data.name, data.bytes);
            var characterInfo = new CharacterInfo[mbFont.glyphs.Count];
            for (var i = 0; i < mbFont.glyphs.Count; i++)
            {
                var bmInfo = mbFont.glyphs[i];
                var info = new CharacterInfo
                {
                    //设置ASCII码  
                    index = bmInfo.index,

                    //设置字符映射到材质上的坐标  
                    uvBottomLeft = new Vector2((float) bmInfo.x/mbFont.texWidth, 1f - (float) (bmInfo.y + bmInfo.height)/mbFont.texHeight),
                    uvBottomRight = new Vector2((float) (bmInfo.x + bmInfo.width)/mbFont.texWidth, 1f - (float) (bmInfo.y + bmInfo.height)/mbFont.texHeight),
                    uvTopLeft = new Vector2((float) bmInfo.x/mbFont.texWidth, 1f - (float) (bmInfo.y)/mbFont.texHeight),
                    uvTopRight = new Vector2((float) (bmInfo.x + bmInfo.width)/mbFont.texWidth, 1f - (float) (bmInfo.y)/mbFont.texHeight),

                    //设置字符顶点的偏移位置和宽高  
                    minX = bmInfo.offsetX,
                    minY = -bmInfo.offsetY - bmInfo.height,
                    maxX = bmInfo.offsetX + bmInfo.width,
                    maxY = -bmInfo.offsetY,

                    //设置字符的宽度  
                    advance = bmInfo.advance
                };
                characterInfo[i] = info;
            }
            myFont.characterInfo = characterInfo;
            EditorUtility.SetDirty(myFont); //设置变更过的资源  
            EditorUtility.SetDirty(mat); //设置变更过的资源  
            AssetDatabase.SaveAssets(); //保存变更的资源  
            AssetDatabase.Refresh(); //刷新资源，貌似在Mac上不起作用  

            //由于上面fresh之后在编辑器中依然没有刷新，所以暂时想到这个方法，  
            //先把生成的字体导出成一个包，然后再重新导入进来，这样就可以直接刷新了  
            //这是在Mac上遇到的，不知道Windows下面会不会出现，如果不出现可以把下面这一步注释掉  
            AssetDatabase.ExportPackage(fontPathName, "temp.unitypackage");
            AssetDatabase.DeleteAsset(fontPathName);
            AssetDatabase.ImportPackage("temp.unitypackage", true);
            AssetDatabase.Refresh();

            Debug.Log("创建字体成功");
        }
    }
}